package com.xgry.bpm.config.shiro;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    @Bean
    public AuthRealm authRealm(){
        AuthRealm authRealm = new AuthRealm();
        // 依赖凭证匹配器
        //myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        // 启用缓存
        authRealm.setCachingEnabled(true);
        // 启用身份验证缓存，即缓存AuthenticationInfo
        authRealm.setAuthenticationCachingEnabled(true);
        // 启用授权缓存，即缓存AuthorizationInfo的信息
        authRealm.setAuthorizationCachingEnabled(true);
        return authRealm;
    }


    /**
     * 会话管理器
     */
    @Bean
    public DefaultWebSessionManager defaultWebSessionManager() {
        DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();
        defaultWebSessionManager.setSessionIdUrlRewritingEnabled(false);
        defaultWebSessionManager.setGlobalSessionTimeout(1800000);
        defaultWebSessionManager.setDeleteInvalidSessions(true);
        defaultWebSessionManager.setSessionValidationSchedulerEnabled(true);
        defaultWebSessionManager.setSessionIdCookieEnabled(true);
        return defaultWebSessionManager;
    }


    //  import org.apache.shiro.mgt.SecurityManager; 这个包
    @Bean("securityManager")
    public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm){
        DefaultWebSecurityManager manager  = new DefaultWebSecurityManager();
        manager.setRealm(authRealm);
        return manager;
    }




    //4.
    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") SecurityManager manager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(manager);
        bean.setLoginUrl("/pages/login.html");
        bean.setSuccessUrl("/pages/index.html");
        bean.setUnauthorizedUrl("/unauthorized");//访问 没有权限的页面时，将会被重定向到此链接，需在 Controller设置页面
//        1). anon 可以被 匿名访问
//        2). authc 必须认证（登录）才能访问
//        3). logout 登出
//        4). roles 角色过滤器
        LinkedHashMap<String,String> filterChainDefinitionMap = new LinkedHashMap<>();

        filterChainDefinitionMap.put("/index","authc");
        filterChainDefinitionMap.put("/pages/login/**", "anon");
        filterChainDefinitionMap.put("/BPM/**", "anon");
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/images/**", "anon");
        filterChainDefinitionMap.put("/miniUI/**", "anon");
        filterChainDefinitionMap.put("/code/**", "anon");
        filterChainDefinitionMap.put("/login.do", "anon");
        filterChainDefinitionMap.put("/loginuser","anon");
        //filterChainDefinitionMap.put("/admin","roles[admin]");
        //filterChainDefinitionMap.put("/edit","perms[edit]");//具有edit权限的才能访问
        filterChainDefinitionMap.put("/druid/**","anon");//开放druid的监控后台

        filterChainDefinitionMap.put("/**","user");
        //bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return bean;
    }







    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
    //Shiro与Spring的关联 开启利用注解配置权限
    /**
     * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
     *
     * 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager")SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }
}
